/**
*  \file defines.h
*
*  \brief global macro definitions
*
*  \author Ralf Guetlein <guetlein@straubtec.de>
*
*  the macros in this header are widely used in system and application files
*
*
*/

#ifndef DEFINES_H_INCLUDED
#define DEFINES_H_INCLUDED

#ifndef DEFINES_LINKAGE
#define DEFINES_LINKAGE extern
#endif


/** attribute for bit data in bit addressing section */
#define __bit _bit

/** attribute for data in near addressing section */
#define __near __attribute__((asection(".sdata.test", "a = 4", "f=aws")))

/** bit-addressable data (e.g. structs with bitfields */
#define __bitadr __attribute__((asection(".zdata", "a = 4", "f=awz")))
#define __bita   __bitadr

/** calculate the size of a memory object in numbers of 16bit words */
#ifndef WORDSIZE
#define WORDSIZE(buf) ((sizeof(buf)+1)/sizeof(S16))
#endif
///\page bitfields
///defining bitfields
///  usage:   var = B8(1, 0, 0, 1, 1, 0, 1, 0);
///  or:      #define MASK B4(1,1,0,1)
///\n
///bitfield types:
///- B4()
///- B8()
///- B16()

///nibble bitfield
///\see bitfields
#define B4(a,b,c,d) (a<<3|b<<2|c<<1|d)
///byte bitfield
///\see bitfields
#define B8(a,b,c,d,e,f,g,h) (B4(a,b,c,d)<<4|B4(e,f,g,h))
///word bitfield
///\see bitfields
#define B16(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p)\
               (B8(a,b,c,d,e,f,g,h)<<8|B8(i,j,k,l,m,n,o,p))

/** run only once
    Macro to be used in functions that may be called only once in an application.
    Usage:

    void function (void)
    {
       RUN_ONLY_ONCE
       {
       }
    }
*/
#define RUN_ONLY_ONCE                 \
   static _bit __onceflag;            \
   for ( ; __onceflag == 0; __onceflag = 1)

/** Inline.
*
* Wraper for the inline keyword. The keyword inline is defined in ANSI 99 but
* various (non ANSI 99) compiler support this feature, but sometimes with an
* other notation.
*/
#define INLINE inline

/** Static inline.
*
*  Wraper for the static inline function. With this macro you can declare a function to
*  do a compiler requested to perform inline expansion of the function.
*  Inline expansion is used to eliminate the time overhead when a function is called.
*  It is typically used for functions that execute frequently.
*  It also has a space benefit for very small functions, and is an enabling transformation
*  for other optimizations.
*/
#define STATIC_INLINE static __inline


/** Restricted.
*
* Wraper for the restricted keyword. The keyword restricted is defined in
* ANSI 99. For non ANSI99 compiler this define should be empty.
*/
#define RESTRICTED
#define RESTRICT

/** Register.
*
* Wraper for the register keyword. The keyword register is part of the ANSI
* definition but is suspected (by Misra) to cause problems.
* Anyway it can be handled with use of this wrapper.
*/
#define REGISTER  register


/** Unreferenced
*
*  The UNREFERENCED macro have to be used to indicate that the variable or parameter
*  is unused and is not refereced. The use of this macro can also prevent compiler
*  warnings.
*/
#define UNREFERENCED(arg)   ((void)arg)


#endif //!DEFINES_H_INCLUDED

